/**
 * @author zdz8207
 * 通用面向对象脚本库
 * @version 1.0
 * 
 */
var coos = function(){this.version = "1.0";};

/**
 * 创建对象和方法的通用函数，兼容多种浏览器，实现高效、方便的继承体系，解决多种常规创建的性能问题
 * @param parantObj jsonObj
 * @example 
 * var Person = coos.Class      //默认派生自object基本类
({
    Create: function(name, age)
    {
        this.base();    //调用上层构造函数
        this.name = name;
        this.age = age;
    },
    SayHello: function()
    {
        alert("Hello, I'm " + this.name + ", " + this.age + " years old.");
    },
    toString: function()    //覆写toString方法
    {
        return this.name;
    }
});

var Employee = coos.Class(Person,    //派生自Person类
{
    Create: function(name, age, salary)
    {
        this.base(name, age);  //调用基类的构造函数
        this.salary = salary;
    },
    ShowMeTheMoney: function()
    {
        alert(this + " $" + this.salary); //这里直接引用this将隐式调用toString()
    }
});
var BillGates = new Person("Bill Gates", 53);
var SteveJobs = new Employee("Steve Jobs", 53, 1234);
alert(BillGates);   //这里将隐式调用覆写后的toString()方法
BillGates.SayHello();
SteveJobs.SayHello();
SteveJobs.ShowMeTheMoney();

var LittleBill = new BillGates.Type("Little Bill", 6); //用BillGate的类型建LittleBill
LittleBill.SayHello();

alert(BillGates.isA(Person));       //true
alert(BillGates.isA(Employee));     //false
alert(SteveJobs.isA(Person));       //true
* 
 */
coos.Class = function()
{
    var aDefine = arguments[arguments.length-1]; //最后一个参数是类定义
    if(!aDefine) return;
    var aBase = arguments.length>1 ? arguments[0] : coos.object; //解析基类
    
    function prototype_(){}; //构造prototype的临时函数，用于挂接原型链
    prototype_.prototype = aBase.prototype;  //准备传递prototype
    var aPrototype = new prototype_();    //建立类要用的prototype
    
    for(var member in aDefine)  //复制类定义到当前类的prototype
    {
        if(member!="Create")    //构造函数不用复制
        {
            aPrototype[member] = aDefine[member];
        }
    }
    //根据是否继承特殊属性和性能情况，可分别注释掉下列的语句
    if(aDefine.toString != Object.prototype.toString)
    {
        aPrototype.toString = aDefine.toString;
    }
    if(aDefine.toLocaleString != Object.prototype.toLocaleString)
    {
        aPrototype.toLocaleString = aDefine.toLocaleString;
    }
    if(aDefine.valueOf != Object.prototype.valueOf)
    {
        aPrototype.valueOf = aDefine.valueOf;
    }
    if(aDefine.Create)  //若有构造函数
    {
        var aType = aDefine.Create;  //类型即为该构造函数
    }
    else    //否则为默认构造函数
	{
        aType = function()
        {
            this.base.apply(this, arguments);   //调用基类构造函数
        };
	}

    aType.prototype = aPrototype;   //设置类(构造函数)的prototype
    aType.Base = aBase;             //设置类型关系，便于追溯继承关系
    aType.prototype.Type = aType;   //为本类对象扩展一个Type属性
    return aType;   //返回构造函数作为类
};

//根类object定义：
coos.object = function(){};    //定义小写的object根类，用于实现最基础的方法等
coos.object.prototype.isA = function(aType)   //判断对象是否属于某类型
{
    var self = this.Type;
    while(self)
    {
        if(self == aType) return true;
        self = self.Base;
    }
    return false;
};

coos.object.prototype.base = function()  //调用基类构造函数
{
    var Base = this.Type.Base;  //获取当前对象的基类  
    if(!Base.Base)  //若基类已没有基类
    {
        Base.apply(this, arguments);     //则直接调用基类构造函数
    }
    else    //若基类还有基类         
    {
        this.base = MakeBase(Base);     //先覆写this.base
        Base.apply(this, arguments);    //再调用基类构造函数
        delete this.base;               //删除覆写的base属性
    }
    function MakeBase(Type) //包装基类构造函数
    {
        var Base = Type.Base;
        if(!Base.Base) return Base; //基类已无基类，就无需包装
        return function()   //包装为引用临时变量Base的闭包函数
        {
            this.base = MakeBase(Base);     //先覆写this.base
            Base.apply(this, arguments);    //再调用基类构造函数
        }
    }
};
/**
 * 扩展函数功能
 * @param destination 要扩展的函数
 * @param source 扩展函数
 * @example
 coos.extend(Array.prototype,{
	clear : function () 
	{
		this.length = 0;
		return this;
	},
	first : function () 
	{
		return this[0];
	},
	last : function () 
	{
		return this[this.length - 1];
	}
});
 */
coos.extend = function(destination, source) {
  for (var property in source)
  {
    destination[property] = source[property];
  }
  return destination;
};

/**
 * simple inherit whit call parent this attribute
 * @param parentFunction
 */
coos.call = function(parentFunction)
{
	var parentfn = parentFunction + ".call(this)";
	eval(parentfn);
};

/**
 * override method
 * @param origclass, overrides the overrides is a json or hashmap
 */
coos.override = function(origclass, overrides)
{
    if(overrides)
    {
        var p = origclass.prototype;
        for(var method in overrides)
        {
            p[method] = overrides[method];
        }
    }
};

/**
 * 克隆对象
 */
coos.clone = function(obj)
{
	var temp = null;
	for(var p in obj)
	{
		temp[p] = obj[p];
	}
	return temp;
};

/**
 * 通用接口函数，为实现设计模式提供支持
 * @param name String类型 接口名称
 * @param methods 字符串数组，每个字符串都是一个必须的方法名称
 * @example 
 	//test coos.Interface 
	var testInterface = new coos.Interface("testInterface",["getId","getName"]);
	
	function adminUser(user)
	{
		//传入的user对象必须实现testInterface的方法
		coos.Interface.impl(user,testInterface);
		//由上面的接口保证了user对象实现了接口方法可以安全使用
		var id = user.getId();
		var name = user.getName();
		var message = "I'm a admin user";
		alert("id = " + id + " name = " + name + " message = " + message);
	}
	
	function vipUser(user)
	{
		//传入的user对象必须实现testInterface的方法
		coos.Interface.impl(user,testInterface);
		//由上面的接口保证了user对象实现了接口方法可以安全使用
		var id = user.getId();
		var name = user.getName();
		var message = "I'm a vip user";
		alert("id = " + id + " name = " + name + " message = " + message);
	}
	
	function user(id,name)
	{
		this.getId = function(){return id};
		this.getName = function(){return name};
	}
	
	adminUser(new user("1","admin"));
	vipUser(new user("2","zdz"));
 * 
 */
coos.Interface = function(name, methods) {
    if(arguments.length != 2) {
        throw new Error("Interface constructor called with " + arguments.length + "arguments, but expected exactly 2.");
    }
    
    this.name = name;
    this.methods = [];
    for(var i = 0, len = methods.length; i < len; i++) {
        if(typeof methods[i] !== 'string')
        {
            throw new Error("Interface constructor expects method names to be " + "passed in as a string.");
        }
        this.methods.push(methods[i]);        
    }    
};

/**
 * 最少传入两个参数，一个为对象，另外为要实现的接口，可传入多个接口
 * 在使用接口方法前作判断coos.Interface.impl(user,testInterface);
 */
coos.Interface.impl = function(object) {
    if(arguments.length < 2) {
        throw new Error("Function Interface.impl called with " + 
          arguments.length  + "arguments, but expected at least 2.");
    }

    for(var i = 1, len = arguments.length; i < len; i++) 
    {
        var _interface = arguments[i];
        if(_interface.constructor !== coos.Interface)
        {
            throw new Error("Function Interface.impl expects arguments "   
              + "two and above to be instances of Interface.");
        }
        
        for(var j = 0, methodsLen = _interface.methods.length; j < methodsLen; j++)
        {
            var method = _interface.methods[j];
            if(!object[method] || typeof object[method] !== 'function')
            {
                throw new Error("Function Interface.impl: object " 
                  + "does not implement the " + _interface.name 
                  + " interface. Method " + method + " was not found.");
            }
        }
    } 
};

/**
 * 反射机制的简单实现
 * @param obj 传入对象为obj类型,可以是json形式的
 * 
 */
coos.reflection = function(obj)
{
	for(var p in obj)
	{
		if(typeof(obj[p]) == "function")
		{
			//如果属性为function类型则执行
			obj[p]();
		}
	}
};

/**
 * 利用闭包构造一个单例类型返回，不能创建新的实例
 * @param fn 闭包函数function(){}的形式
 * @param singletonName 创建的单例类型名称
 * @example
	 var sessionFactory = new coos.singleton(
		function(){
			this.message = "I'm a sessionFactory!";
			this.sayHello = function(){alert("Hello!");}
		},"sessionFactory"
	);
	var mySession = sessionFactory.getInstance();
	mySession.sayHello();
	var newSession = new sessionFactory();// throw 单例类型sessionFactory不能实例化!
 */
coos.singleton = function(fn,singletonName)
{
	singletonName = singletonName || "singletonClass";
	var obj = new fn();
	var singletonClass = function()
	{
		throw new Error("单例类型" + singletonName + "不能实例化！");
	};
	singletonClass.getInstance = function(){return obj;};
	singletonClass.name = singletonName;
	return singletonClass;
};

/**
 * 定义通用的简单命令模式接口
 */
coos.command = new coos.Interface("coos.command",["execute"]);

/**
 * 定义通用的带取消操作的命令模式接口
 */
coos.undocommand = new coos.Interface("coos.undocommand",["execute","undo"]);

/**
 * aop 的实现
 * @param object 必须为对象，不能是方法本身
 * @example
 function aopTest()
{
    this.say1 =  function(s)
	{
        alert(s);
    };
    this.say2 =  function(s)
	{
        alert(s);
    };  
}
   
function beforeHander()
{
    alert("aspect said:");
}
function afterHander()
{
	alert("said by aspect");
}
  

var test = new aopTest();
coos.aop(test);
test.before("say1",beforeHander); 
test.after("say1",afterHander);
test.say1("hello I'm say1");

test.before("say2",beforeHander);
test.after("say2",afterHander);
test.say2("hello I'm say2");
 */
coos.aop = function(object)
{
	if(typeof(object) != "object")
	{
		throw new Error("传入的对象类型必须为object！");
		return false;
	}
	object.yield = null;
	object.rv = {};
	object.before  = function(method, f)
	{
		var original = eval("this." + method);
		this[method] = function()
		{
		  f.apply(this, arguments);
		  return original.apply(this, arguments);
		};
	};   
	object.after = function(method, f)
	{
	    var original = eval("this." + method);
	    this[method] = function()
	    {
	      this.rv[method] = original.apply(this, arguments);
	      return f.apply(this, arguments);
	    };
	};   
	object.around = function(method, f)
	{
    	var original = eval("this." + method);
    	this[method] = function()
	    {
	      this.yield = original;
	      return f.apply(this, arguments);
	    };
	};
};

/**
 * 采用prototype的Object扩展方法
 * @param obj 需要判断的对象
 */
coos.extend(Object, {
	extend : function(destination, source) {
	  for (var property in source)
	    destination[property] = source[property];
	  return destination;
	},
	toJSON: function(object) {
    var type = typeof object;
    switch (type) {
      case 'undefined':
      case 'function':
      case 'unknown': return;
      case 'boolean': return object.toString();
    }

    if (object === null) return 'null';
    if (object.toJSON) return object.toJSON();
    if (Object.isElement(object)) return;

    var results = [];
    for (var property in object) {
      var value = Object.toJSON(object[property]);
      if (!Object.isUndefined(value))
        results.push(property.toJSON() + ': ' + value);
    }
    return '{' + results.join(', ') + '}';
  },
  keys: function(object) {
    var keys = [];
    for (var property in object)
      keys.push(property);
    return keys;
  },
  values: function(object) {
    var values = [];
    for (var property in object)
      values.push(object[property]);
    return values;
  },
  clone: function(object) {
    return Object.extend({ }, object);
  },
  isElement: function(object) {
    return object && object.nodeType == 1;
  },
  isArray: function(object) {
  	//判断是否为数组，考虑到多种情况
  	return Object.prototype.toString.call(object) === '[object Array]';
    //return object != null && typeof object == "object" && 'splice' in object && 'join' in object;
  },
  isHash: function(object) {
    return object instanceof Hash;
  },
  isFunction: function(object) {
    return typeof object == "function";
  },
  isString: function(object) {
    return typeof object == "string";
  },
  isNumber: function(object) {
    return typeof object == "number";
  },
  isUndefined: function(object) {
    return typeof object == "undefined";
  }
});

/**
 * json的处理函数
 * parse函数把json字符串转换成对象
 * toJSONString把对象转换成json字符串(包括普通对象和json对象)
 */
coos.json = {
	parse : function(data)
	{
		if(typeof(data) != "object")
		{
			data = eval('(' + data + ')');
		}
		return data;
	},
	toJSONString : function(obj)
	{
		switch(typeof(obj))
		{
			case "object" :
			{
				var result = [];
				if(obj instanceof Array)
				{
					var len = obj.length;
					for(var i = 0; i < len; i++)
					{
						result.push(coos.json.toJSONString(obj[i]));
					}
					return "[" + result.toString(",") + "]";
				}
				else if(obj instanceof RegExp)
				{
					return obj.toString();
				}
				else
				{
					for(var attribute in obj)
					{
						result.push(attribute + ":" + coos.json.toJSONString(obj[attribute]));
					}
					return "{" + result.join(",") + "}";
				}
			}
			case "function":
			{
				return "function(){}";
			}
			case "number":
			{
				return obj.toString();
			}
			case "boolean":
			{
				return obj.toString();
			}
			case "string":
			{
				return "\"" + obj.replace(/(\\|\")/g, "\\$1").replace(/\n|\r|\t/g,function(a){return ("\n" == a) ? "\\n":("\r" == a) ? "\\r":("\t" == a) ? "\\t":"";}) + "\"";
			}
			default:
			{
				return obj.toString();
			}
		}
	}
};

/**
 * browser userAgent
 */
coos.userAgent = navigator.userAgent.toLowerCase();
/**
 * Figure out what browser is being used 
 * typeof(window.external.max_version) in some ie7.0 is unkonwn not undefined
 * @example 
if(coos.browser.msie){alert("ie browser "+"version="+ coos.browser.version);}
if(coos.browser.maxthon){alert("maxthon browser "+"version="+ coos.browser.maxthonVersion);};
alert(coos.browser.maxthon + " maxthon browser "+"version= "+ coos.browser.maxthonVersion);
 */
coos.browser = {
	version: (coos.userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
	safari: /webkit/.test(coos.userAgent) &&  !/chrome/.test(coos.userAgent),
	chrome: /chrome/.test(coos.userAgent),
	opera: /opera/.test(coos.userAgent),
	msie: /msie/.test(coos.userAgent) && !/opera/.test(coos.userAgent),
	firefox: /firefox/.test(coos.userAgent),
	mozilla: /mozilla/.test(coos.userAgent) && !/(compatible|webkit)/.test(coos.userAgent),
	maxthon: (window.external && (typeof(window.external.max_version) == "string"))?true:false,
	maxthonVersion: (window.external && (typeof(window.external.max_version) == "string"))?window.external.max_version.substr(0,1):undefined
};

/**
 * 简单的兼容浏览器的onload事件绑定
 * @param fn 需要绑定window.onload后执行的function
 */
coos.onloadEvent = function(fn)
{
	if (window.addEventListener) 
	{
		window.addEventListener("load",fn,false);
	}
	else if(window.attachEvent)
	{
		window.attachEvent("onload", fn);
	}
	else
	{
		window.onload = fn;
	}
};
/**
 * 根据id快速获取dom对象的方法,直接用$方便使用和符合其它框架的习惯
 * @param id 字符串类型
 * @return DOM element
 */
coos.$ = function(id)
{
  return document.getElementById(id);
};

/**
 * 在不确定传入id还是obj类型时快速获取dom对象的方法,用$$方便使用和记忆
 * @param el 元素id或对象
 * @return DOM element
 */
coos.$$ = function(el)
{
  var obj = el;
	if(typeof(el) == "string")
	{
		obj = document.getElementById(el);
	}
	return obj;
};

/**
 * 根据id快速获取dom对象的方法
 * @param id 字符串类型
 * @return DOM element
 */
coos.$id = function(id)
{
  return document.getElementById(id);
};

/**
 * 根据name快速获取dom对象的方法
 * @param name 字符串类型
 * @return DOM elements
 */
coos.$name = function(name)
{
  return document.getElementsByName(name);
};

/**
 * 在不确定传入id还是obj类型时快速获取dom对象的方法
 * @param el 元素id或对象
 * @return DOM element
 */
coos.$obj = function(el)
{
	var obj = el;
	if(typeof(el) == "string")
	{
		obj = document.getElementById(el);
	}
	return obj;
};

/**
 * 获取元素下面所有传入类型的对象.
 * @param tag 标签名称
 * @param el 元素id或对象,为空或不存在则默认为document
 * @example
 获取id为testTag的div下所有li对象为：coos.$tag("li","testTag");
 获取所有li对象为：coos.$tag("li");
 */
coos.$tag = function(tag,el)
{
	var el = coos.$obj(el) || document;
	return el.getElementsByTagName(tag);
};

/**
 * 获取元素的类型名称(如div span)
 */
coos.$tagName = function(el)
{
	return coos.$obj(el).tagName.toLowerCase();
};

/**
 * 获取iframe的contentWindow对象
 */
coos.$F = function(el)
{
	if(!coos.$obj(el) || coos.$tagName(el) != "iframe")
	{
		return null;
	}
	return coos.$obj(el).contentWindow;
};

/**
 * 取得某个范围内的随机数
 */
coos.$random = function(min, max)
{
	return Math.floor(Math.random() * (max - min + 1) + min);
};

/**
 * 获得当前时间
 */
coos.$time = function()
{
	return new Date().getTime();
};

/**
 * 返回document.body
 */
coos.$body = function()
{
	return document.body;
};

/**
 * 获取元素的innerHTML内容
 * @param el 元素id或对象,默认为document.body
 */
coos.$html = function(el)
{
	var obj = coos.$obj(el)|| document.body;
	return 	obj.innerHTML;
};

/**
 * 获取head
 */
coos.$head = function()
{
	return 	document.getElementsByTagName('head')[0];
};

/**
 * 获取元素的文本内容
 * @param el 元素id或对象
 */
coos.$text = function(el)
{
	var obj = coos.$obj(el);
	return 	obj.textContent || obj.innerText;
};

/**
 * 创建元素
 * coos.$create("div")返回一个未绑定到DOM上的div对象
 */
coos.$create = function(tag)
{
	return document.createElement(tag);
};

/**
 * 添加元素
 * @param el 要添加子元素的父元素
 * @param 要添加的子元素
 */
coos.$append = function(el,child)
{
	coos.$obj(el).appendChild(coos.$obj(child));
};

/**
 * 删除元素对应的class
 */
coos.$removeClass = function(className,el)
{
	coos.$obj(el).className = coos.$obj(el).className.replace(new RegExp("( ?|^)" + className + "\\b"), "");
};

/**
 * 判断元素是否有该class
 */
coos.$hasClass = function(className,el)
{
	var oReg = new RegExp("( ?|^)" + className + "\\b");
	return oReg.test(coos.$obj(el).className);
};

/**
 * 判断元素是否有该class
 */
coos.$addClass = function(className,el)
{
	var el = coos.$obj(el);
	if(coos.$hasClass(className,el))
	{
		return;
	}
	else
	{
		el.className = el.className + " " + className;
	}
};

/**
 * 删除元素下对应标签元素所有对应的样式
 */
coos.$removeTagClass = function(className,tag,el)
{
	var els = coos.$tag(tag,el);
	var len = els.length;
	for(var i = 0; i < len; i++)
	{
		coos.$removeClass(className,els[i]);
	}
};

/**
 * 获取元素下对应标签下对应样式的所有元素
 */
coos.$getTagClassElements = function(className,tag,el)
{
	var els = coos.$tag(tag,el);
	var result = [];
	var len = els.length;
	for(var i = 0; i < len; i++)
	{
		if(coos.$hasClass(className,els[i]))
		{
			result[result.length] = els[i];
		}
	}
	return result;
};

/**
 * 隐藏元素，可以传入id或对象
 */
coos.$hide = function(el)
{
	coos.$obj(el).style.display = "none";
};

/**
 * 显示元素，可以传入id或对象
 */
coos.$show = function(el)
{
	coos.$obj(el).style.display = "";
};

/**
 * 此元素下所有对应标签的元素
 */
coos.$hiddenTag = function(tag,el)
{
	var els = coos.$tag(tag,el);
	var len = els.length;
	for(var i = 0; i < len; i++)
	{
		els[i].style.display = "none";
	}
};

/**
 * 获取非position定位的元素top属性值
 */
coos.$top = function(el)
{
	var obj = coos.$obj(el);
	if(coos.browser.msie)
	{
		var top = 0;
	}
	else
	{
		var top = 2;
	}
	while(obj.offsetParent)
	{
		top += obj.offsetTop + (obj.currentStyle?(parseInt(obj.currentStyle.borderTopWidth)).NaN0():0);
		obj = obj.offsetParent;
	}
	top += obj.offsetTop + (obj.currentStyle?(parseInt(obj.currentStyle.borderTopWidth)).NaN0():0);
	
	return top;
};

/**
 * 获取非position定位的元素left属性值
 */
coos.$left = function(el)
{
	var obj = coos.$obj(el);
	if(coos.browser.msie)
	{
		var left = -2;
	}
	else
	{
		var left = 0;
	}
	while(obj.offsetParent)
	{
		left += obj.offsetLeft + (obj.currentStyle?(parseInt(obj.currentStyle.borderLeftWidth)).NaN0():0);
		obj = obj.offsetParent;
	}
	left += obj.offsetLeft + (obj.currentStyle?(parseInt(obj.currentStyle.borderLeftWidth)).NaN0():0);
	
	return left;
};

/**
 * 动态插入脚本并执行
 * @param scriptStr
 * @param el dom元素对象或ID 可以不传入
 * @exsample coos.$script("<script>alert(2);<\/script>");
 */
coos.$script = function(scriptStr,el)
{
	var el = coos.$obj(el);
	if(!el){
		var div = coos.$create("div");
		div.style.display = "none";
		coos.$append(document.body,div);
		el = div;
	}
	if(coos.browser.msie){
		scriptStr = '<div style="display:none">ie</div>' + scriptStr;
		//当节点被移除的时候，ie会重新解析节点内部的html，有脚本则会执行相关的脚本，script要加上defer属性
		scriptStr = scriptStr.replace(/<script([^>]*)>/gi,'<script$1 defer>');
		el.innerHTML = scriptStr;
		el.removeChild(el.firstChild);
	}else{
		var el_next = el.nextSibling;
		var el_parent = el.parentNode;
		el_parent.removeChild(el);
		el.innerHTML = scriptStr;
		if (el_next) {
			el_parent.insertBefore(el, el_next);
		}else {
			el_parent.appendChild(el);
		}
	}
};

/**
 * 插入html代码，解决火狐下不能直接插入html字符串的问题
 * @param where 插入相对el对象的位置：before 插入到之前，top插入到最前面，bottom插入到最后，after插入到之后
 * @param el 插入的相对元素 默认为document.body
 * @param html 插入的html字符串
 * @exsample coos.$insert("top","testDiv","<div>test coos.$insert html</div>");
 */
coos.$insert = function(where, el, html)
{
	var el = coos.$obj(el) || document.body;
	where = where.toLowerCase();   
	if(el.insertAdjacentHTML)
	{
	    switch(where)
	    {   
	        case "before":   
	            el.insertAdjacentHTML('beforeBegin', html);   
	            return el.previousSibling;
	            break;
	        case "top":   
	            el.insertAdjacentHTML('afterBegin', html);   
	            return el.firstChild;
	            break;
	        case "bottom":   
	            el.insertAdjacentHTML('beforeEnd', html);   
	            return el.lastChild;
	            break; 
	        case "after":   
	            el.insertAdjacentHTML('afterEnd', html);   
	            return el.nextSibling;
	            break;
	    }
	    throw 'Illegal insertion point -> "' + where + '"';   
	}
	
	var range = el.ownerDocument.createRange();   
    var frag;
    switch(where)
    {   
         case "before":   
            range.setStartBefore(el);   
            frag = range.createContextualFragment(html);   
            el.parentNode.insertBefore(frag, el);   
            return el.previousSibling;
            break;
         case "top":   
            if(el.firstChild)
            {   
                range.setStartBefore(el.firstChild);   
                frag = range.createContextualFragment(html);   
                el.insertBefore(frag, el.firstChild);   
                return el.firstChild;
            }else
            {   
                el.innerHTML = html;   
                return el.firstChild;   
            }
            break;
        case "bottom":   
            if(el.lastChild)
            {   
                range.setStartAfter(el.lastChild);   
                frag = range.createContextualFragment(html);   
                el.appendChild(frag);   
                return el.lastChild;   
            }
            else
            {   
                el.innerHTML = html;   
                return el.lastChild;   
            }
            break;
        case "after":   
            range.setStartAfter(el);   
            frag = range.createContextualFragment(html);   
            el.parentNode.insertBefore(frag, el.nextSibling);   
            return el.nextSibling; 
            break;  
        }   
        throw 'Illegal insertion point -> "' + where + '"';
};
//一加载脚本就需要初始化的函数，避免对象不存在的错误。
(function(){
/**
 * 添加样式
 */
coos.style = {
	add : function(content)
	{
		var style = null;
	    if(document.all)
	    {
	        style = document.createStyleSheet();
	        style.cssText = content;
	    }
	    else
	    {
	        style = document.createElement("style");
	        style.type = "text/css";
	        //style.innerHTML = content;//Safari、Chrome 下innerHTML只读
	        style.textContent = content;
	        try
	        {
	    		document.getElementsByTagName("head")[0].appendChild(style);
	    	}
	    	catch(e){}
	    }
	}
};

/**
 * 提供url常用操作功能
 * random 在url后面加入随机数参数
 * getAttribe 获得url中的参数值
 * replaceAttribe 替换url中的参数值
 * addAttribe 添加参数
 * getAction 获得url中action的名字(后缀可变)
 * location url跳转
 */
coos.url = {
	random : function(url)
	{
		if (url.indexOf ("?") > 0)
		{
			url = url + "&random=" + new Date().getTime();
		}
		else
		{
			url = url + "?random=" + new Date().getTime();
		}
		return url;
	},
	getAttribe : function(type,url)
	{
		var url = url || location.href;
		var urltemp = url.split(type + "=")[1];
		if(!urltemp) return "";
		if(urltemp.indexOf("&") == -1) 
		{
			return urltemp;
		}
		else
		{
			return urltemp.split("&")[0];
		}
	},
	replaceAttribe : function(type,value,url)
	{
		var url = url || location.href;
		
		var oReg = new RegExp(type + "=([^&]+)?","g");
		
		url= url.replace(oReg, type + "=" + value);
		return url;
	},
	addAttribe : function(type,value,url)
	{
		var url = url || location.href;
		if(url.indexOf ("?") == -1)
		{
			return (url + "?" + type + "=" + value);
		}
		else
		{
			return (url + "&" + type + "=" + value);
		}
	},
	getAction : function(url,action)
	{
		var url = url || location.href;
		var action = action || ".action";
		var temp = url.split(action)[0];
		return temp.substring(temp.lastIndexOf("/")+1,temp.length);
	},
	location : function(url,message)
	{
		var url = url || location.href;
		if(!message)
		{
			window.location = url;
			return false; 
		}
		if(confirm(message))
		{
			window.location = url;
		}
		return false; 
	}
};

/**
 * iframe的处理函数
 * 提供批量和单独iframe自适应高度功能
 */
coos.iframe = {
	autoHeights : function(els)
	{
		for (var i = 0; i < arguments.length; i++) 
		{
	        coos.iframe.autoHeight(arguments[i]);
	    }
	},
	autoHeight : function(el)
	{
		var obj = coos.$obj(el);
		var id = obj.id;
		var subWeb = document.frames ? document.frames[id].document : obj.contentDocument;   
		if(obj != null && subWeb != null)
		{
			//iframe body 设置为height:100%;时火狐下最小高度为150
			obj.height = parseInt(subWeb.body.scrollHeight) + "px";
		   
		}
	},
	onload : function(el,fn)
	{
		var ifr = coos.$obj(el);
		//IE中iframe只支持隐形的onload事件,需要通过attachEvent来注册，ie的readystatechange事件有一些潜在的问题
		if(ifr.attachEvent)
		{
			ifr.attachEvent("onload",fn);
		}
		else
		{
			ifr.onload = fn;
		}
	}
};

/**
 * cookie的处理函数
 */
coos.cookie = {
	set : function(name,value,days,path,domain,secure)
	{
		var days = days || 100;
		var path = path || "/";
		var domain = domain || "";
		var secure = secure || "";
	    var exp  = new Date();
	    exp.setTime(exp.getTime() + days*24*60*60*1000);
	    document.cookie = name + "="+ escape (value) 
	    + ";expires=" + exp.toGMTString()
	    + ";path="+ path
	    + (domain == "" ? "" : ("; domain=" + domain))
	    + (secure ? "; secure" : "");
	},
	get : function(name)
	{
		var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)"));
		if(arr != null)
			return unescape(arr[2]);
		return null;
	},
	del : function(name)
	{
		var exp = new Date();
	    exp.setTime(exp.getTime() - 1);
	    var cval=this.get(name);
	    if(cval!=null)
	    	document.cookie= name + "="+cval+";expires="+exp.toGMTString();
	}
};

/**
 * form相关的通用函数
 */
coos.form = {
	submit : function(formElement,submitId)
	{
		if(!coos.$obj(formElement))return false;
		var submitId = submitId || "subButton";
		coos.$id(submitId).disabled = true;
		coos.$obj(formElement).submit();
		return false;
	},
	update : function(formElement,formName,action)
	{
		if(formName)
			formElement.name = formName;
		if(action)
			formElement.action = action;
	},
	validate : function(){}
};

})();
//初始化函数结束

/**
 * 引入script和css文件
 */
coos.include = function()
{
	function create(path)
	{
		var src = path.split("|")[0];
		var charset = path.split("|")[1];
		var sobj = document.createElement('script'); 
		sobj.type = "text/javascript"; 
		sobj.src = src;
		sobj.charset = charset || "utf-8";
		document.getElementsByTagName('head')[0].appendChild(sobj);
	}
	
	function getScriptPath(key)
	{
		var scripts = document.getElementsByTagName("script");
		var len = scripts.length;
		for (var i = 0; i < len; i++)
		{
			if(scripts[i].src.indexOf(key) != -1)
			{
				return scripts[i].src.split(key)[0];
			}
		}
		return null;
	}
	//获得script的路径，只传入文件名则默认为coos.js同一个目录
	function path(src,key)
	{
		if(src.indexOf("/") != -1)
		{
			return src;
		}
		else
		{
			var key = key || "coos.js";
			return getScriptPath(key) + src;
		}
	}
	
	return{
		script : function()
		{
			var len = arguments.length;
			
			for(var i = 0; i < len; i++)
			{
				create(path(arguments[i]));
			}
		},
		css : function()
		{
			var len = arguments.length;
			
			for(var i = 0; i < len; i++)
			{
				var css = document.createElement("link");
				css.rel = "stylesheet";
				css.type = "text/css";
				css.href = path; 
				create(css);
			}
		}
	}
	
}();

//由于导入文件太多可能导致难以预料的问题，把主要函数开发稳定后合并在同类脚本里面可以减少不必要的异常
//需要设定charset属性的在文件后面加上|编码，如：coos.ext.base.js|gbk，coos.ext.base.js|utf-8，默认为utf-8
coos.include.script("coos.ext.base.js");
coos.include.script("coos.ui.base.js");
//ajax用到的地方比较多，用户每个页面自己导入比较麻烦
coos.include.script("coos.ext.ajax.js");
